package com.icoding.fw.utils;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.transform.Transformers;

public class NativeQuery {
	private Query query;
	private Session session;

	public NativeQuery(Session session) {
		this.setSession(session);
	}

	public Session getSession() {
		return session;
	}

	public void setSession(Session session) {
		this.session = session;
	}

	@SuppressWarnings("rawtypes")
	public Query createSQLQuery(String sql, Class clazz) {
		query = getSession().createSQLQuery(sql).addEntity(clazz);
		return query;
	}

	@SuppressWarnings("rawtypes")
	public Query createSQLQueryWithDTO(String sql, Class clazz) {
		SQLQuery sqlQuery = getSession().createSQLQuery(sql);
		List<String> listStr = NameDTOParse.init()
				.getNameFieldAnnotation(clazz);
		for (String str : listStr) {
			query = sqlQuery.addScalar(str);
		}
		return query.setResultTransformer(Transformers.aliasToBean(clazz));
	}

	/**
	 * @param position
	 * @param val
	 * @return
	 */
	public Query setParameter(int position, Object val) {
		return query.setParameter(position, val);
	}

	/**
	 * @param name
	 * @param val
	 * @return
	 */
	public Query setParameter(String name, Object val) {
		return query.setParameter(name, val);
	}

	/**
	 * @param position
	 * @param val
	 * @param type
	 * @return
	 */
	public Query setParameter(int position, Object val,
			org.hibernate.type.Type type) {
		return query.setParameter(position, val, type);
	}

	/**
	 * @param name
	 * @param val
	 * @param type
	 * @return
	 */
	public Query setParameter(String name, Object val,
			org.hibernate.type.Type type) {
		return query.setParameter(name, val, type);
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> list() {
		return query.list();
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public <T> List<T> listDTO(String sql, Class clazz) {
		return createSQLQueryWithDTO(sql, clazz).list();
	}

	// Return query of sql
	public String getQuery() {
		return query.getQueryString();
	}

	public int executeUpdate() {
		return query.executeUpdate();
	}
}
